/*
 * @file iso9660.c
 *
 *   ISO9660 I/O interface
 */
#if HAVE_CONFIG_H
#include "config.h"
#endif

#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>

#include <rtems.h>
#include <rtems/seterr.h>

#include "iso9660.h"
#include "iso9660_io.h"


ssize_t
iso9660_read_sector(
    iso9660_fs_info_t    *fs,
    uint32_t              sector_num,
    uint32_t              offset,
    uint32_t              count,
    void                 *buffer
)
{
  ssize_t             bytes = 0;
  int                 rc;

  if (rtems_iso9660_volume_is_block(fs)) {
    rtems_bdbuf_buffer *block = NULL;
    uint32_t            chunk_size;
    int                 blocknum;

    blocknum = (sector_num * ISO9660_SECTOR_SIZE ) / rtems_iso9660_block_size(fs);

    while (count > 0) {
      rc = iso9660_buffer_acquire(fs, blocknum, &block);
      if (rc)
        return rc;

      chunk_size = MIN(count, rtems_iso9660_block_size(fs) - offset);
      memcpy(((unsigned char*)buffer + bytes), (block->buffer + offset), chunk_size);

      blocknum++;
      count -= chunk_size;
      bytes += chunk_size;
      offset = 0;
    }
  } else if (rtems_iso9660_volume_is_regular(fs)) {
      rc = lseek(rtems_iso9660_device_descriptor(fs), sector_num * ISO9660_SECTOR_SIZE + offset, SEEK_SET);
      if (rc == -1)
        return rc;

      bytes = read(rtems_iso9660_device_descriptor(fs), buffer, count);
  }

  return bytes;
}
